package com.rp.files.controller;


import cn.hutool.core.util.StrUtil;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.model.Filters;
import com.rp.bo.NewAdminBO;
import com.rp.files.config.FileResource;
import com.rp.files.service.UploadService;
import com.rp.news.common.ResponseStatusEnum;
import com.rp.news.common.Result;
import com.rp.news.exception.GraceException;
import com.rp.news.util.FileUtils;
import com.rp.news.util.extent.AliImageReviewUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件操作controller
 */
@RestController
@Slf4j
@Api(value = "files 文件上次相关接口文档", tags = {"文件操作 api文档"})
@RequestMapping("/fs")
public class FileUploadController {

    @Autowired
    private UploadService uploadService;

    @Autowired
    private FileResource fileResource;

    @Autowired
    private AliImageReviewUtils aliImageReviewUtils;

    @Autowired
    private GridFSBucket gridFSBucket;


    public static final String FAILED_IMAGE_URL = "https://imooc-news.oss-cn-shanghai.aliyuncs.com/image/faild.jpeg";

    @ApiOperation(value = "上次用户头像", notes = "上次用户头像", httpMethod = "POST")
    @PostMapping("/uploadFace")
    public Result uploadFace(String userId, MultipartFile file) throws Exception {

        if (file == null) {
            return Result.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            return Result.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String[] split = originalFilename.split("\\.");
        //获取后缀
        String suffix = split[split.length - 1];

        if (!"png".equalsIgnoreCase(suffix) || !"jpg".equalsIgnoreCase(suffix) || !"jpeg".equalsIgnoreCase(suffix)) {
            return Result.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        String path = uploadService.uploadFastDfs(file, suffix);
        //String path = uploadService.uploadOSS(file, userId, suffix);
        String finalPath = "";
        if (StrUtil.isNotBlank(path)) {
            finalPath = fileResource.getHost() + path;
            //finalPath = fileResource.getOssHost() + path;
        } else {
            return Result.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        return Result.ok(finalPath);
        //return Result.ok(doAliImageReview(finalPath));
    }

    @ApiOperation(value = "上传多文件", notes = "上传多文件", httpMethod = "POST")
    @PostMapping("/uploadSomeFiles")
    public Result uploadSomeFiles(String userId, MultipartFile[] files) throws Exception {
        List<String> imagesUrlList = new ArrayList<>();


        if (files != null && files.length > 0) {

            for (int i = 0; i < files.length; i++) {

                String path = "";
                MultipartFile file = files[i];
                String originalFilename = file.getOriginalFilename();
                if (StrUtil.isBlank(originalFilename)) {
                    continue;
                }

                String[] split = originalFilename.split("\\.");
                //获取后缀
                String suffix = split[split.length - 1];

                if (!"png".equalsIgnoreCase(suffix) || !"jpg".equalsIgnoreCase(suffix) || !"jpeg".equalsIgnoreCase(suffix)) {
                    continue;
                }
                path = uploadService.uploadFastDfs(file, suffix);
                //path = uploadService.uploadOSS(file, userId, suffix);
                String finalPath = "";
                if (StrUtil.isNotBlank(path)) {
                    finalPath = fileResource.getHost() + path;
                    //finalPath = fileResource.getOssHost() + path;
                } else {
                    //return Result.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
                    continue;
                }
                //todo fixme:放入List之前要对image进行图片审核
                imagesUrlList.add(path);
            }

        }

        return Result.ok(imagesUrlList);
        //return Result.ok(doAliImageReview(finalPath));    }
    }

    /**
     * 文件上次到mongodb 的gridfs中
     *
     * @param newAdminBO
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "上次用户头像", notes = "上次用户头像", httpMethod = "POST")
    @PostMapping("/uploadToGridFS")
    public Result uploadToGridFS(@RequestBody NewAdminBO newAdminBO) throws Exception {
        String img64 = newAdminBO.getImg64();
        byte[] bytes = new BASE64Decoder().decodeBuffer(img64.trim());
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectId objectId = gridFSBucket.uploadFromStream(newAdminBO.getAdminName() + ".png", byteArrayInputStream);
        String fileId = objectId.toString();
        return Result.ok(fileId);
    }

    /**
     * 文件mongodb 的gridfs中读取图片内容
     */
    @ApiOperation(value = "上次用户头像", notes = "上次用户头像")
    @GetMapping("/readInGridFS")
    public void readInGridFS(@RequestParam("faceId") String faceId,HttpServletResponse response) throws
            Exception {
        if (StrUtil.isBlank(faceId)) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }
        File file = readGridFSByFaceId(faceId);
        FileUtils.downloadFileByStream(response, file);
    }


    /**
     * 从文件mongodb 的gridfs中读取base64图片内容
     */
    @ApiOperation(value = "从文件mongodb 的gridfs中读取base64图片内容", notes = "从文件mongodb 的gridfs中读取base64图片内容", httpMethod = "GET")
    @GetMapping("/readFace64InGridFS")
    public Result readFace64InGridFS(String faceId, HttpServletRequest request, HttpServletResponse response) throws
            Exception {
        File file = readGridFSByFaceId(faceId);
        String s = FileUtils.fileToBase64(file);
        return Result.ok(s);
    }


    private File readGridFSByFaceId(String faceId) throws Exception {
        GridFSFindIterable gridFSFindIterable = gridFSBucket.find(Filters.eq("_id", new ObjectId(faceId)));
        GridFSFile first = gridFSFindIterable.first();

        if (first == null) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }
        String filename = first.getFilename();
        log.info("filename============>{}", filename);
        String tempPath = "/Users/rp/workspace/rp-new/temp_face";
        File file = new File(tempPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File file1 = new File(tempPath + File.separator + filename);
        FileOutputStream fileOutputStream = new FileOutputStream(file1);
        gridFSBucket.downloadToStream(new ObjectId(faceId), fileOutputStream);


        return file1;

    }


    /**
     * 图片内容安全校验
     *
     * @param pendingImageUrl
     * @return
     */
    private String doAliImageReview(String pendingImageUrl) {
        boolean result = false;

        try {
            result = aliImageReviewUtils.reviewImage(pendingImageUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!result) {
            return FAILED_IMAGE_URL;
        }
        return pendingImageUrl;
    }
}
